﻿using System;
using Microsoft.Xna.Framework;

namespace XNAGameEngine.GameState
{
    /// <summary>
    /// Abstract class that all game states must inherit
    /// </summary>
    public abstract class GameState
    {
        #region local fields

        //the string value associated with this state
        protected internal string _stringReference;

        //the state of this game state object
        private GSState _state;

        //allows callbacks to the GameStateManager
        protected IManagerGameState _stateManager;

        #endregion

        #region properties

        /// <summary>
        /// Returns the string value associated with this state
        /// </summary>
        public string _GSOType { get { return _stringReference; } }

        /// <summary>
        /// Returns the GSOState of this GameStateObject (ACTIVE, INACTIVE, LOADING, UNLOADING)
        /// </summary>
        public GSState _GSOState { get { return _state; } }

        /// <summary>
        /// Provides a direct reference to the GameEngine
        /// </summary>
        public Game Game { get { return _stateManager.Game; } }

        #endregion

        #region constructors

        /// <summary>
        /// Constructor stores the GameStateEngine and the string value inside the GameStateObject
        /// </summary>
        /// <param name="stringReference">the game state string reference value</param>
        /// <param name="stateEngine">the GameStateManager object managing this GameStateObject</param
        public GameState(string stringReference, IManagerGameState stateManager)
        {
            _stringReference = stringReference;
            _stateManager = stateManager;
        }

        #endregion

        #region local methods

        /// <summary>
        /// <para>Initialize the GameStateObject</para>
        /// <para>When you override this method, you must call base.Initialize()</para>
        /// </summary>
        public virtual void Initialize()
        {
            _state = GSState.LOADING;
        }

        /// <summary>
        /// <para>Cleanup the GameStateObject. This is called just before the new state is transitioned in.</para>
        /// <para>Garbage collection is invoked.</para>
        /// <para>When you override this method, you must call base.Cleanup()</para>
        /// </summary>
        public virtual void Cleanup()
        { }

        /// <summary>
        /// <para>Pauses the GameStateObject</para>
        /// <para>When you override this method, you must call base.Pause()</para>
        /// </summary>
        public virtual void Pause()
        {
            _state = GSState.INACTIVE;
        }

        /// <summary>
        /// <para>Unpauses the GameStateObject</para>
        /// <para>When you override this method, you must call base.Resume()</para>
        /// </summary>
        public virtual void Resume()
        {
            _state = GSState.ACTIVE;
        }

        /// <summary>
        /// <para>Update the GameState for this frame</para>
        /// <para>When you override this method, you must call base.Update()</para>
        /// </summary>
        public virtual void Update(GameTime gameTime)
        { }

        /// <summary>
        /// <para>Draw the GameStateObject to the screen.</para>
        /// <para>When you override this method, you must call base.Draw()</para>
        /// </summary>
        public virtual void Draw(GameTime gameTime)
        { }

        /// <summary>
        /// <para>Called to start the transition out of the GameStateObject.</para>
        /// <para>Called before Cleanup() to start the transition. </para>
        /// </summary>
        public void PreCleanup()
        {
            _state = GSState.UNLOADING;
        }

        #endregion
    }
}